#!/bin/bash

#  cmdex: the small script do something to help you.
#  you can execute command in every directory and its subdirectory.
#  designer: Swaper@RainStudio

slfName=$(basename $0)

oldIFS=IFS
curPath=""
strCmd=""
strArgs=""
showDir=0
hasCmd=0
objDirs=$#

IFS=""
for i in $*; do
  if [ ${i:0:3} == "/c:" ]; then
    strCmd=${i:3}
    hasCmd=1
    objDirs=$[$objDirs-1]
  fi
  if [ ${i:0:3} == "/a:" ]; then
    if [ -z $strArgs ]; then
      strArgs=${i:3}
    else
      strArgs="$strArgs ${i:3}"
    fi
    objDirs=$[$objDirs-1]
  fi
  if [ ${i:0:2} == "/d" ]; then
    showDir=1
    objDirs=$[$objDirs-1]
  fi
done

if [ $hasCmd -eq 0 ]; then
  echo "$slfName: usage: $slfName: path /c:command /a:arg1 /a:arg2 ..."
  echo "option /d show working directory."
  echo "examples:"
  echo "  $slfName /home/myhome /c:ls"
  echo "  $slfName /home/myhome /c:ls /a:-l"
  echo "hint:"
  echo "if you have some arguments include space such as"
  echo "  \"01234 56789\""
  echo "  \"a b c\""
  echo "you can write them into a script as a command."
  IFS=$oldIFS
  exit 1;
fi

dirs -c
pushd +0 > /dev/null
curPath=$(dirs -l +0)

fcCmdex( )
{
  if [ ${i:0:3} != "/c:" ] && [ ${i:0:3} != "/a:" ] &&
    [ ${i:0:2} != "/d" ] && [ -d $i ] && ! [ -L $i ]; then
    workDir=$i
    pushd $workDir > /dev/null
    workDir=$(dirs -l +0)

    while [ true ]; do
      IFS=" "
      $strCmd $strArgs
      IFS=""
      popd > /dev/null
      if [ $showDir -eq 1 ]; then
        echo $workDir
      fi
      for j in $workDir/*; do
        if [ -d $j ] && ! [ -L $j ]; then
          pushd $j > /dev/null
        fi
      done
      for j in $workDir/.*; do
        if [ $j != "$workDir/." ] && [ $j != "$workDir/.." ] &&
          [ -d $j ] && ! [ -L $j ]; then
          pushd $j > /dev/null
        fi
      done
      workDir=$(dirs -l +0)
      if [ $workDir == $curPath ]; then
        break
      fi
    done
  fi
}

if [ $objDirs -eq 0 ]; then
  i=$curPath
  fcCmdex
else
  for i in $*; do
    fcCmdex
  done
fi

IFS=$oldIFS
